package com.fneuch.w40k.mathammer;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.fneuch.mwg.GameSystem;
import com.fneuch.mwg.army.ArmyList;
import com.fneuch.mwg.army.Unit;
import com.fneuch.mwg.profiles.ModelProfile;
import com.fneuch.mwg.rules.AttackResult;
import com.fneuch.mwg.rules.CombatUnitRole;
import com.fneuch.w40k.exception.ResourceNotFoundException;

@Controller
@RequestMapping("/mathammer")
@Scope("session")
public class MathammerController {
	public static final String VIEW_NAME = "mathammer";
	public static final String REDIRECT_VIEW_NAME = "redirect:/"
			+ VIEW_NAME;

	@Autowired
	private GameSystem gameSystem;
	private AttackResult lastShootingResult;
	private AttackResult lastCloseCombatResult;
	
	@RequestMapping(method = RequestMethod.GET)
	public String get() {
        executeAttack();

		return VIEW_NAME;
	}

	private void executeAttack() {
		if(!gameSystem.getAttackers().isEmpty() && !gameSystem.getDefenders().isEmpty()) {
        	lastShootingResult = gameSystem.executeShooting();
        	lastCloseCombatResult = gameSystem.executeCloseCombat();
        } else {
        	lastShootingResult = null;
        	lastCloseCombatResult = null;
        }
	}
	
	@RequestMapping(value = "/{unitsRoles}/{modelName}", method = RequestMethod.DELETE)
	public String delete(@PathVariable("unitsRoles") String unitsRoles,
			@PathVariable("modelName") String modelName) {
		boolean throwException = false;
		Unit unit = getUnit(unitsRoles);
		if (unit != null) {
			// devons nous lancé l'exception si on demande de supprimer qqe
			// choses qui n'existe plus...???
			unit.removeModelbyName(modelName);

		} else {
			throwException = true;
		}

		if (throwException) {
			throw new ResourceNotFoundException();
		}

        executeAttack();
		return REDIRECT_VIEW_NAME;
	}

	@RequestMapping(value = {"/add", "/ajouter"}, method = RequestMethod.POST)
	public String add(@ModelAttribute("model") @Valid ModelFormBean model, BindingResult result) {
		return addByRoles(model.getUnitRole(), model, result);
	}

	@RequestMapping(value = {"/{unitsRoles}/add", "/{unitsRoles}/ajouter"}, method = RequestMethod.POST)
	public String addByRoles(@PathVariable("unitsRoles") String unitsRoles,
			@ModelAttribute("model") @Valid ModelFormBean model, BindingResult result) {
		CombatUnitRole ut = CombatUnitRole.getbyString(unitsRoles);
		if (result.hasErrors()) {
			return VIEW_NAME;
		}
		Unit unit = getUnit(ut);
		unit.ajouterModel(model.getQuantity(), model);
		ArmyList armyList = getArmyList(ut);
		armyList.remove(0);
		armyList.add(unit);

        executeAttack();
		return REDIRECT_VIEW_NAME;
	}
	
	@ModelAttribute("shootingResult")
	public AttackResult getShootingResult() {
		return lastShootingResult;
	}
	
	@ModelAttribute("ccResult")
	public AttackResult getCloseCombatResult() {
		return lastCloseCombatResult;
	}
	
	@ModelAttribute("attackers")
	public List<ModelFormBean> getAttaquants() {
		if(gameSystem.getAttackers().isEmpty()){
			gameSystem.getAttackers().add(new Unit("attacker"));
		}
		List<ModelFormBean> models = new ArrayList<ModelFormBean>();
		for(ModelProfile model: gameSystem.getAttackers().get(0).getModels().keySet()) {
			models.add(new ModelFormBean(model));
		}
		return models;
	}
	
	@ModelAttribute("defenders")
	public List<ModelFormBean> getDefenders() {
		if(gameSystem.getDefenders().isEmpty()){
			gameSystem.getDefenders().add(new Unit("defender"));
		}
		List<ModelFormBean> models = new ArrayList<ModelFormBean>();
		for(ModelProfile model: gameSystem.getDefenders().get(0).getModels().keySet()) {
			models.add(new ModelFormBean(model));
		}
		return models;
	}
	
//	@ModelAttribute("listRoles") 
//	public List<String> getUnitRoles(){
//		List<String> unitRoles = new ArrayList<String>();
//		unitRoles.add(CombatUnitRole.ATTACKERS.toString());
//		unitRoles.add(CombatUnitRole.DEFENDERS.toString());
//		return unitRoles;		
//	}
	
	@ModelAttribute("model")
	public ModelFormBean createModelFormBean() {
		return new ModelFormBean();
	}
	
	@SuppressWarnings("unused")
	private ArmyList getArmyList(String unitsRoles) {
		CombatUnitRole ut = CombatUnitRole.getbyString(unitsRoles);
		return getArmyList(ut);
	}

	private ArmyList getArmyList(CombatUnitRole ut) {
		ArmyList armyList = null;
		if (ut != null) {
			switch (ut) {
			case ATTACKERS:
				armyList = (ArmyList) gameSystem.getAttackers();
				break;
			case DEFENDERS:
				armyList = (ArmyList) gameSystem.getDefenders();
				break;
			}
		}
		return armyList;
	}
	
	private Unit getUnit(String unitsRoles) {
		CombatUnitRole ut = CombatUnitRole.getbyString(unitsRoles);
		return getUnit(ut);
	}

	private Unit getUnit(CombatUnitRole unitsRoles) {
		Unit unit = getArmyList(unitsRoles).get(0);
		if(unit == null) {
			unit = new Unit(unitsRoles.getSingleUnitRole());
		}
		return unit;
	}
}
